package ac.svn.accesscontrol.ui;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import javax.swing.JLabel;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;

import ac.svn.accesscontrol.manager.SVNInfoManager;
import ac.svn.accesscontrol.store.ISVNItem;
import ac.svn.accesscontrol.store.SVNGroup;
import ac.svn.accesscontrol.store.SVNUser;

/**
 * @author Enigmanic
 *
 */
public class TreePopulator {
	private boolean listClrRequired = false;
	private Thread listingThread;
	private Set<ISVNItem> sourceFiles;
	private JTree svnTree;
	private DefaultMutableTreeNode rootNode;
	private JLabel statusLabel;

	public TreePopulator(String componentId,String rootNodeId)
	{
		svnTree = (JTree) UIComponentLibrary.getComponent(componentId);
		rootNode =  (DefaultMutableTreeNode) UIComponentLibrary.getComponent(rootNodeId);
		statusLabel = (JLabel) UIComponentLibrary.getComponent(IUIConstants.C_STATUS_LABEL);		

		listingThread = new Thread(new Runnable() {
			@Override
			public void run() {

				Map<String,DefaultMutableTreeNode> allNodes = new HashMap<String, DefaultMutableTreeNode>();
				Map<String,Set<String>> group2UserMap = new HashMap<String, Set<String>>();

				if(null == sourceFiles || sourceFiles.isEmpty())
				{
					return;
				}

				if(isListClrRequired())
				{
					rootNode.removeAllChildren();
				}

				for(ISVNItem  svnItem  : sourceFiles )
				{
					SVNGroup svnGroup = (SVNGroup) svnItem;
					DefaultMutableTreeNode groupNode = (DefaultMutableTreeNode) UIComponentLibrary.getComponent(svnGroup.getGroupAlias());
					if(null == groupNode)
					{
						groupNode = new DefaultMutableTreeNode(svnGroup);
					}					
					groupNode.setUserObject(svnGroup);
				

					allNodes.put(svnGroup.getGroupAlias(),groupNode);
					Set<String> allUsers = new TreeSet<String>();
					for(String userAlias: svnGroup.getGroupMembers())
					{
						SVNUser svnUser = SVNInfoManager.getInfoManager().getSvnUser(userAlias);
						DefaultMutableTreeNode userNode = new DefaultMutableTreeNode(svnUser);
						String key = svnUser.getName() + "#"  +svnGroup.getGroupAlias();
						UIComponentLibrary.addComponent(key, userNode);						
						allNodes.put(key, userNode);
						allUsers.add(svnUser.getUserAlias());
					}
					group2UserMap.put(svnGroup.getGroupAlias(), allUsers);
					UIComponentLibrary.addComponent(svnGroup.getGroupAlias(), groupNode);
				}

				List<String> list = new ArrayList<String>(group2UserMap.keySet());
				Collections.sort(list);
				for(String group: list)
				{
					DefaultMutableTreeNode gn = allNodes.get(group);
					Set<String> allMembers = group2UserMap.get(group);
					for(String user: allMembers)
					{
						String key = user + "#" + group;
						DefaultMutableTreeNode un = allNodes.get(key);
						gn.add(un);
					}
					rootNode.add(gn);					
				}


				SwingUtilities.invokeLater(new Runnable() {
					@Override
					public void run() {
						SwingUtilities.updateComponentTreeUI(svnTree);
						if(isListClrRequired())
						{
							statusLabel.setText("Listing complete!");
						}					
					}
				});

			}
		});
	}

	public void listItem(Set<ISVNItem> svnItems)
	{
		sourceFiles = null;
		sourceFiles =  svnItems;
		refresh();
	}

	public void setListClrRequired(boolean listClrRequired) {
		this.listClrRequired = listClrRequired;
	}

	public boolean isListClrRequired() {
		return listClrRequired;
	}

	public void refresh()
	{
		if(listingThread.isAlive())
		{
			listingThread.interrupt();
		}
		listingThread.run();
	}

	public void addItem(ISVNItem svnItem)
	{
		sourceFiles.add(svnItem);
		refresh();
	}

}